home *** CD-ROM | disk | FTP | other *** search
Java Source | 2000-09-28 | 9.4 KB | 298 lines |
- /*
- * QuickTime for Java SDK Sample Code
-
- Usage subject to restrictions in SDK License Agreement
- * Copyright: © 1996-1999 Apple Computer, Inc.
-
- */
-
- import java.awt.*;
- import java.awt.event.*;
- import java.io.*;
-
- import quicktime.qd.*;
- import quicktime.*;
- import quicktime.std.*;
- import quicktime.io.*;
- import quicktime.sound.*;
- import quicktime.std.image.*;
- import quicktime.std.movies.*;
- import quicktime.std.movies.media.*;
- import quicktime.util.*;
-
- import createmovies.*;
-
- import quicktime.app.display.*;
- import quicktime.app.image.*;
- import quicktime.app.QTFactory;
- /**
- * CreateMovie Demo.
- */
-
- public class CreateMovie extends Frame implements StdQTConstants, Errors {
- static CreateMovie movieFrame;
-
- //_________________________ CLASS METHODS
- public static void main(String args[]) {
- try {
- QTSession.open();
-
- movieFrame = new CreateMovie("Movie Creation Demo using QuickTime and Java");
- movieFrame.addWindowListener (new WindowAdapter () {
- public void windowOpened (WindowEvent we) {
- movieFrame.makeMovie();
- }
- public void windowClosing (WindowEvent e) {
- movieFrame.canv.removeClient();
- QTSession.close();
- movieFrame.dispose();
- }
- public void windowClosed (WindowEvent e) {
- System.exit(0);
- }
- });
- movieFrame.show();
- movieFrame.toFront();
- } catch (Exception e) {
- e.printStackTrace();
- QTSession.close();
- }
- }
-
- public CreateMovie (String frameTitle) throws Exception {
- super(frameTitle);
- soundFile = QTFactory.findAbsolutePath ("sound.aif");
-
- canv = new QTCanvas (QTCanvas.kInitialSize, 0.5F, 0.5F);
- add ("Center", canv);
-
- np = new NumberPainter(numFrames);
- qid = new QTImageDrawer (np, new Dimension (kWidth, kHeight), Redrawable.kMultiFrame);
- qid.setRedrawing(true);
-
- canv.setClient (qid, true);
-
- pack();
- }
-
- //_________________________ INSTANCE VARIABLES
- private QTCanvas canv;
- private QTImageDrawer qid;
- private NumberPainter np;
- private static final int numFrames = 30;
- private int kWidth = 330;
- private int kHeight = 140;
- private File soundFile;
-
- //_________________________ INSTANCE METHODS
- private void makeMovie() {
- try {
- //
- // show save-as dialog, create movie file & empty movie
- //
- FileDialog fd = new FileDialog (this, "Save Movie As...", FileDialog.SAVE);
- fd.show();
- if(fd.getFile() == null)
- throw new QTIOException (userCanceledErr, "");
- QTFile f = new QTFile(fd.getDirectory() + fd.getFile());
- Movie theMovie = Movie.createMovieFile (f,
- kMoviePlayer,
- createMovieFileDeleteCurFile | createMovieFileDontCreateResFile);
-
- //
- // add content
- //
- System.out.println ("Doing Video Track");
- addVideoTrack( theMovie );
- System.out.println ("Doing Audio Track");
- addAudioTrack( theMovie );
-
- //
- // save movie to file
- //
- OpenMovieFile outStream = OpenMovieFile.asWrite (f);
- theMovie.addResource( outStream, movieInDataForkResID, f.getName() );
- outStream.close();
- System.out.println ("Finished movie");
- }
- catch (Exception qte) {
- qte.printStackTrace();
- }
- }
-
- private void addVideoTrack (Movie theMovie) throws QTException {
- int kNoVolume = 0;
- int kVidTimeScale = 600;
-
- Track vidTrack = theMovie.addTrack (kWidth, kHeight, kNoVolume);
- VideoMedia vidMedia = new VideoMedia (vidTrack, kVidTimeScale);
-
- vidMedia.beginEdits();
- addVideoSample (vidMedia);
- vidMedia.endEdits();
-
- int kTrackStart = 0;
- int kMediaTime = 0;
- int kMediaRate = 1;
- vidTrack.insertMedia (kTrackStart, kMediaTime, vidMedia.getDuration(), kMediaRate);
- }
-
- private void addVideoSample( VideoMedia vidMedia ) throws QTException {
- QDRect rect = new QDRect (kWidth, kHeight);
- QDGraphics gw = new QDGraphics (rect);
- int size = QTImage.getMaxCompressionSize (gw,
- rect,
- gw.getPixMap().getPixelSize(),
- codecNormalQuality,
- kAnimationCodecType,
- CodecComponent.anyCodec);
- QTHandle imageHandle = new QTHandle (size, true);
- imageHandle.lock();
- RawEncodedImage compressedImage = RawEncodedImage.fromQTHandle(imageHandle);
- CSequence seq = new CSequence (gw,
- rect,
- gw.getPixMap().getPixelSize(),
- kAnimationCodecType,
- CodecComponent.bestFidelityCodec,
- codecNormalQuality,
- codecNormalQuality,
- numFrames, //1 key frame
- null, //cTab,
- 0);
- ImageDescription desc = seq.getDescription();
-
- //redraw first...
- np.setCurrentFrame (1);
- qid.redraw(null);
-
- qid.setGWorld (gw);
- qid.setDisplayBounds (rect);
-
- for (int curSample = 1; curSample <= numFrames; curSample++) {
- np.setCurrentFrame (curSample);
- qid.redraw(null);
- CompressedFrameInfo info = seq.compressFrame (gw,
- rect,
- codecFlagUpdatePrevious,
- compressedImage);
- boolean isKeyFrame = info.getSimilarity() == 0;
- System.out.println ("f#:" + curSample + ",kf=" + isKeyFrame + ",sim=" + info.getSimilarity());
- vidMedia.addSample (imageHandle,
- 0, // dataOffset,
- info.getDataSize(),
- 60, // frameDuration, 60/600 = 1/10 of a second, desired time per frame
- desc,
- 1, // one sample
- (isKeyFrame ? 0 : mediaSampleNotSync)); // no flags
- }
-
- //print out ImageDescription for the last video media data ->
- //this has a sample count of 1 because we add each "frame" as an individual media sample
- System.out.println (desc);
-
- //redraw after finishing...
- qid.setGWorld (canv.getPort());
- np.setCurrentFrame (numFrames);
- qid.redraw(null);
- }
-
- static class SoundData {
- QTHandle sampleData;
- SoundDescription description;
- int numSamples;
- }
-
- private void addAudioTrack (Movie theMovie) throws QTException, IOException {
- int kFullVolume = 1;
-
- // fills in the above SoundData class fields
- SoundData theSound = getSound();
-
- //print out the SoundDescription
- System.out.println (theSound.description);
-
- //create Sound track with SoundMedia object -> the rounded sample rate is the time scale of the sound media
- Track sndTrack = theMovie.addTrack (0, 0, kFullVolume);
- SoundMedia sndMedia = new SoundMedia (sndTrack, theSound.description.getSampleRateRounded());
-
- //add the sample data into the sound media
- sndMedia.beginEdits();
- sndMedia.addSample (theSound.sampleData,
- 0,
- theSound.sampleData.getSize(),
- 1, // duration of each sound sample,
- theSound.description,
- theSound.numSamples,
- 0);
- sndMedia.endEdits();
-
- // insert the media into the track
- int kTrackStart = 0;
- int kMediaTime = 0;
- int kMediaRate = 1;
- sndTrack.insertMedia (kTrackStart, kMediaTime, sndMedia.getDuration(), kMediaRate);
- }
-
- private SoundData getSound() throws QTException, IOException {
- //
- // read sound.aif file into memory and create a description and read the sound data out of it.
- //
-
- SndInfo info = SndInfo.parseAIFFHeader (OpenFile.asRead (new QTFile(soundFile)));
-
- SoundData sd = new SoundData();
-
- SoundComponentData mySndInfo = info.sndData;
-
- sd.description = new SoundDescription (mySndInfo.getFormat());
- sd.description.setNumberOfChannels (mySndInfo.getNumChannels());
- sd.description.setSampleSize (mySndInfo.getSampleSize());
- sd.description.setSampleRate (mySndInfo.getSampleRate());
-
- int mySampleDataSize = mySndInfo.getSampleCount() * (mySndInfo.getSampleSize() / 8);
- //read just the sample data into memory
- // it is sample data size and is found at the data offset location in the file
- // as returned by the ParseAIFF header call
- FileInputStream fis = new FileInputStream (soundFile);
- byte[] ar = new byte [mySampleDataSize];
- fis.skip (info.dataOffset);
- fis.read (ar, 0, mySampleDataSize);
-
- sd.sampleData = new QTHandle (ar);
-
- sd.numSamples = mySndInfo.getSampleCount();
- return sd;
- }
- }
-
-
- /* THIS way captures the result of the draw method of the QTImageDrawer
- it then adds the raw pixel data to the movie, getting that raw data and description
- from the ImagePresenter of the QTImageDrawer
-
- the way we add data above is to compress the GWorld the QTImageDrawer draws to
- using the animation compressor -> which also gives us frame differencing and a smalller data size
- and better playback for the movie.
-
- this code is presented as an alternative which may be appropriate in certain instances
- -> like adding image data for a sprite where no fidelity on each image is lost.
- in this case the important point is NOT the QTImageDrawer but the addition
- of the raw EncodedImage and ImageDescription -> how we get that is up to the application.
-
- for (int curSample = 1; curSample <= numFrames; curSample++) {
- QTUtils.reclaimMemory();
- np.setCurrentFrame (curSample);
- qid.redraw(null);
- ImagePresenter ip = qid.toImagePresenter();
- ImageDescription desc = ip.getDescription();
- EncodedImage imageData = ip.getImage(1);
- vidMedia.addSample (QTHandle.fromEncodedImage(imageData),
- 0, // dataOffset,
- desc.getDataSize(),
- 60, // frameDuration, 60/600 = 1/10 of a second, desired time per frame
- desc,
- 1, // one sample
- 0 ); // no flags
- }
- */
-